﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using Gui.Net.Properties;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;


namespace Gui.Net
{
    public partial class Form1 : Form
    {
        private CurrencyManager cm;
        public Form1()
        {
            InitializeComponent();

            listBox1.DataSource = Settings.Default.ApplicationsToMonitor;
            cm = (CurrencyManager)listBox1.BindingContext[Settings.Default.ApplicationsToMonitor];
        }

        private void ShowHide()
        {
            if ( this.Visible )
            {
                WindowHide();
            }
            else
            {
                WindowShow();
            }
        }

        private void WindowShow()
        {
            this.Visible = true;
            this.ShowInTaskbar = true;
            this.WindowState = System.Windows.Forms.FormWindowState.Normal;
        }
        private void WindowHide()
        {
            this.WindowState = System.Windows.Forms.FormWindowState.Minimized;
            this.ShowInTaskbar = false;
            this.Visible = false;
        }
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void showHideToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowHide();
        }

        private bool FindProcess( string processName )
        {

            Process[] processList = Process.GetProcessesByName(processName);
            return processList.Count() > 0;
        }

        /// <summary>
        /// Tries to find running processes from list.
        /// <para>
        /// Enumerates all processes names first. 
        /// Then creates 2 arrays intersection and checks it for empty.
        /// </para>
        /// </summary>
        /// <param name="processNames">process names list to find</param>
        /// <returns>true if one or more specified processes are running</returns>
        private bool FindProcessesIntersect( ref string[] processNames )
        {
            string[] allProcessNames = EnumerateProcessesName();
            return allProcessNames.Intersect(processNames).Count() > 0;
        }

        /// <summary>
        /// Tries to find running processes from list.
        /// <para>
        /// Iterates through specified process names 
        /// and calls Process.GetProcessesByName on each.
        /// If Process.GetProcessesByName result not empty - returnes true
        /// </para>
        /// </summary>
        /// <param name="processNames">process names list to find</param>
        /// <returns>true if one or more specified processes are running</returns>
        private bool FindProcesses(System.Collections.Specialized.StringCollection processNames)
        {
            foreach (string processName in Settings.Default.ApplicationsToMonitor)
            {
                if (FindProcess(Path.GetFileNameWithoutExtension(processName)))
                {
                    return true;
                }
            }
            return false;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (FindProcesses(Settings.Default.ApplicationsToMonitor))
            {
                if ( WinApi.DwmIsCompositionEnabled() )
                {
                    uint ret = WinApi.DwmEnableComposition(0);
                }
            }
            else
            {
                if ( !WinApi.DwmIsCompositionEnabled() )
                {
                    uint ret = WinApi.DwmEnableComposition(1);
                }
            }
            
        }

        private string[] EnumerateProcessesName()
        {
            Process[] processList = Process.GetProcesses();
            string[] processNames = new string[processList.GetLength(0)];

            for (int index = 0;
                index < processList.GetLength(0);
                ++index)
            {
                try
                {
                    string processName = processList[index].MainModule.ModuleName.ToLower();
                    processNames[index] = processName;
                }
                catch (System.Exception)
                {
                    processNames[index] = processList[index].ProcessName;
                }
            }
            
            return processNames;
        }

        private void Form1_Shown(object sender, EventArgs e)
        {
            WindowHide();
        }

        private void addProcessName_Click(object sender, EventArgs e)
        {
            Settings.Default.ApplicationsToMonitor.Add(newProcessName.Text);
            newProcessName.Clear();
            cm.Refresh();
            Settings.Default.Save();
        }

        private void deleteProcessName_Click(object sender, EventArgs e)
        {
            Settings.Default.ApplicationsToMonitor.RemoveAt(listBox1.SelectedIndex);
            cm.Refresh();
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            ApplyChanges();
            WindowHide();
        }

        private void btnApply_Click(object sender, EventArgs e)
        {
            ApplyChanges();
        }

        private void ApplyChanges()
        {
            Settings.Default.Save();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            WindowHide();
        }
    }
}
